<template>
  <el-row>
    <el-col :span="24" class="col-box-show">
      <el-steps :active="step" align-center finish-status="success">
        <el-step title="基本信息"></el-step>
        <el-step title="规格参数"></el-step>
        <el-step title="销售属性"></el-step>
        <el-step title="SKU信息"></el-step>
        <el-step title="保存完成"></el-step>
      </el-steps>
    </el-col>
    <el-col :span="24" v-show="step == 0">
      <el-card class="box-card">
        <el-form :model="spu" label-width="120px">
          <el-form-item label="商品名称" prop="spuName">
            <el-input v-model="spu.spuName"></el-input>
          </el-form-item>
          <el-form-item label="商品描述" prop="spuDescription">
            <el-input v-model="spu.spuDescription"></el-input>
          </el-form-item>
          <el-form-item label="选择分类" prop="catalogId">
            <Cascader></Cascader>
          </el-form-item>
          <el-form-item label="选择品牌" prop="brandId">
            <Select></Select>
          </el-form-item>
          <el-form-item label="商品重量(Kg)" prop="weight">
            <el-input-number
              v-model="spu.weight"
              :min="0"
              :precision="3"
              :step="0.1"
            ></el-input-number>
          </el-form-item>
          <el-form-item label="设置金币" prop="bounds">
            <el-input-number
              placeholder="金币"
              v-model="spu.bounds.buyBounds"
              :min="0"
              controls-position="right"
            ></el-input-number>
          </el-form-item>
          <el-form-item label="设置成长值" prop="bounds">
            <el-input-number
              placeholder="成长值"
              v-model="spu.bounds.growBounds"
              :min="0"
              controls-position="right"
            >
              <template slot="prepend">成长值</template>
            </el-input-number>
          </el-form-item>
          <el-form-item label="商品介绍" prop="decript">
            <multi-upload v-model="spu.decript"></multi-upload>
          </el-form-item>
          <el-form-item label="商品图集" prop="images">
            <multi-upload v-model="spu.images"></multi-upload>
          </el-form-item>
          <el-form-item>
            <el-button type="success" @click="collectSpuBaseInfo">
              下一步：设置基本参数
            </el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </el-col>
    <el-col :span="24" v-show="step == 1">
      <el-card class="box-card">
        <el-tabs tab-position="left" style="width: 98%">
          <el-tab-pane
            :label="group.attrGroupName"
            v-for="(group, gIdx) in dataResp.attrGroups"
            :key="group.attrGroupId"
          >
            <!-- 遍历属性,每个tab-pane对应一个表单，每个属性是一个表单项  spu.baseAttrs[0] = [{attrId:xx,val:}]-->
            <el-form ref="form" :model="spu" label-width="120px">
              <el-form-item
                :label="attr.attrName"
                v-for="(attr, aidx) in group.attrs"
                :key="attr.attrId"
              >
                <el-input
                  v-model="dataResp.baseAttrs[gIdx][aidx].attrId"
                  v-show="false"
                ></el-input>
                <el-select
                  v-model="dataResp.baseAttrs[gIdx][aidx].attrValues"
                  :multiple="attr.valueType == 1"
                  filterable
                  allow-create
                  default-first-option
                  placeholder="请选择或输入值"
                >
                  <el-option
                    v-for="(val, vIdx) in attr.valueSelect.split(';')"
                    :key="vIdx"
                    :label="val"
                    :value="val"
                  ></el-option>
                </el-select>
                <el-checkbox
                  v-model="dataResp.baseAttrs[gIdx][aidx].showDesc"
                  :true-value="1"
                  :false-label="0"
                >
                  快速展示
                </el-checkbox>
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
        <div style="margin: auto">
          <el-button type="primary" @click="prevStep">上一步</el-button>
          <el-button type="success" @click="generateSaleAttrs">
            下一步：设置销售属性
          </el-button>
        </div>
      </el-card>
    </el-col>
    <el-col :span="24" v-show="step == 2">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>选择销售属性</span>
          <el-form ref="saleform" :model="spu">
            <el-form-item
              :label="attr.attrName"
              v-for="(attr, aidx) in dataResp.saleAttrs"
              :key="attr.attrId"
            >
              <el-input
                v-model="dataResp.tempSaleAttrs[aidx].attrId"
                v-show="false"
              ></el-input>
              <el-checkbox-group
                v-model="dataResp.tempSaleAttrs[aidx].attrValues"
              >
                <el-checkbox
                  v-if="dataResp.saleAttrs[aidx].valueSelect != ''"
                  :value="val"
                  :label="val"
                  v-for="val in dataResp.saleAttrs[aidx].valueSelect.split(';')"
                  :key="val"
                ></el-checkbox>
                <div style="margin-left: 1rem; display: inline">
                  <el-button
                    v-show="!inputVisible[aidx].view"
                    class="button-new-tag"
                    size="small"
                    @click="showInput(aidx)"
                  >
                    +自定义
                  </el-button>
                  <el-input
                    v-show="inputVisible[aidx].view"
                    v-model="inputValue[aidx].val"
                    :ref="'saveTagInput' + aidx"
                    size="small"
                    style="width: 150px"
                    @keyup.enter="handleInputConfirm(aidx)"
                    @blur="handleInputConfirm(aidx)"
                  ></el-input>
                </div>
              </el-checkbox-group>
            </el-form-item>
          </el-form>
        </div>
        <el-button type="primary" @click="prevStep">上一步</el-button>
        <el-button type="success" @click="generateSkus">
          下一步：设置SKU信息
        </el-button>
      </el-card>
    </el-col>
    <el-col :span="24" v-show="step == 3">
      <el-card class="box-card">
        <el-table :data="spu.skus" style="width: 100%" :row-key="getRowKey">
          <el-table-column label="属性组合">
            <el-table-column
              :label="item.attrName"
              v-for="(item, index) in dataResp.tableAttrColumn"
              :key="item.attrId"
            >
              <template #default="scope">
                <span style="margin-left: 10px">
                  {{ scope.row.attr[index].attrValue }}
                </span>
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column label="商品名称" prop="skuName">
            <template #default="scope">
              <el-input v-model="scope.row.skuName"></el-input>
            </template>
          </el-table-column>
          <el-table-column label="标题" prop="skuTitle">
            <template #default="scope">
              <el-input v-model="scope.row.skuTitle"></el-input>
            </template>
          </el-table-column>
          <el-table-column label="副标题" prop="skuSubtitle">
            <template #default="scope">
              <el-input v-model="scope.row.skuSubtitle"></el-input>
            </template>
          </el-table-column>
          <el-table-column label="价格" prop="price">
            <template #default="scope">
              <el-input v-model="scope.row.price"></el-input>
            </template>
          </el-table-column>
          <el-table-column type="expand">
            <template #default="scope">
              <multi-upload v-model="scope.row.uploadImages" />
              <div class="image-card-flex-out">
                <el-card
                  class="image-card-flex"
                  :body-style="{ padding: '0px' }"
                  v-for="(img, index) in spu.images"
                  :key="index"
                >
                  <img :src="img" style="width: 148px; height: 148px" alt="" />
                  <div class="image-flex">
                    <div class="image-flex-line">
                      <el-checkbox
                        v-model="scope.row.images[index].imgUrl"
                        :true-value="img"
                        :false-value="undefined"
                      />
                      <el-tag v-if="scope.row.images[index].defaultImg == 1">
                        <input
                          class="image-radio"
                          type="radio"
                          checked
                          :name="scope.row.skuName"
                          @change="checkDefaultImg(scope.row, index, img)"
                        />
                        设为默认
                      </el-tag>
                      <el-tag v-else>
                        <input
                          class="image-radio"
                          type="radio"
                          :name="scope.row.skuName"
                          @change="checkDefaultImg(scope.row, index, img)"
                        />
                        设为默认
                      </el-tag>
                    </div>
                  </div>
                </el-card>
              </div>

              <!-- 折扣，满减，会员价 -->
              <el-form :model="scope.row">
                <el-row>
                  <el-col :span="24">
                    <el-form-item label="设置折扣">
                      <label>满</label>
                      <el-input-number
                        style="width: 160px"
                        :min="0"
                        controls-position="right"
                        v-model="scope.row.fullCount"
                      ></el-input-number>
                      <label>件</label>
                      <label style="margin-left: 15px">打</label>
                      <el-input-number
                        style="width: 160px"
                        v-model="scope.row.discount"
                        :precision="2"
                        :max="1"
                        :min="0"
                        :step="0.01"
                        controls-position="right"
                      ></el-input-number>
                      <label>折</label>
                      <el-checkbox
                        v-model="scope.row.countStatus"
                        :true-value="1"
                        :false-label="0"
                      >
                        可叠加优惠
                      </el-checkbox>
                    </el-form-item>
                  </el-col>
                  <el-col :span="24">
                    <el-form-item label="设置满减">
                      <label>满</label>
                      <el-input-number
                        style="width: 160px"
                        v-model="scope.row.fullPrice"
                        :step="100"
                        :min="0"
                        controls-position="right"
                      ></el-input-number>
                      <label>元</label>
                      <label style="margin-left: 15px">减</label>
                      <el-input-number
                        style="width: 160px"
                        v-model="scope.row.reducePrice"
                        :step="10"
                        :min="0"
                        controls-position="right"
                      ></el-input-number>
                      <label>元</label>
                      <el-checkbox
                        v-model="scope.row.priceStatus"
                        :true-value="1"
                        :false-label="0"
                      >
                        可叠加优惠
                      </el-checkbox>
                    </el-form-item>
                  </el-col>

                  <el-col :span="24">
                    <el-form-item
                      label="设置会员价"
                      v-if="scope.row.memberPrice.length > 0"
                    >
                      <br />
                      <el-form-item
                        v-for="(mp, mpidx) in scope.row.memberPrice"
                        :key="mp.id"
                      >
                        {{ mp.name }}
                        <label style="padding-left: 8px">优</label>
                        <el-input-number
                          style="width: 160px; margin-bottom: 20px"
                          v-model="scope.row.memberPrice[mpidx].price"
                          :precision="2"
                          :min="0"
                          controls-position="right"
                        ></el-input-number>
                      </el-form-item>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
            </template>
          </el-table-column>
        </el-table>
        <div class="next-bottom">
          <el-button type="primary" @click="prevStep">上一步</el-button>
          <el-button el-button type="success" @click="submitSkus">
            下一步：保存商品信息
          </el-button>
        </div>
      </el-card>
    </el-col>
    <el-col :span="24" v-show="step == 4">
      <el-card class="box-card" style="margin: 20px auto">
        <h1>保存成功</h1>
        <el-button type="primary" @click="addAgain">继续添加</el-button>
      </el-card>
    </el-col>
  </el-row>
</template>
<script setup lang="ts">
import Cascader from '@/views/common/cascader.vue'
import Select from '@/views/common/select.vue'
import MultiUpload from '@/components/upload/multiUpload.vue'
import { ref, watch } from 'vue'
import { reqAttrsList, reqBaseList, reqSaveSpu } from '@/api/product/spu'
import catBrandStore from '@/store/modules/spu.ts'
import { storeToRefs } from 'pinia'
import { ElMessage, ElMessageBox } from 'element-plus'

interface Sku {
  attr: Array<{ attrId: any; attrName: string; attrValue: any }>
  skuName: string
  price: number
  skuTitle: string
  skuSubtitle: string
  images: Array<{ imgUrl: string; defaultImg: number }>
  descar: string[]
  fullCount: number
  discount: number
  countStatus: number
  fullPrice: number
  reducePrice: number
  priceStatus: number
  memberPrice: Array<{ id: number; name: string; price: number }>
}

const step = ref(0)
const spu = ref<{
  spuName: string
  spuDescription: string
  catalogId: number
  brandId: number
  weight: number
  publishStatus: number
  decript: any[]
  images: any[]
  bounds: {
    buyBounds: number
    growBounds: number
  }
  baseAttrs: { attrId: number; attrValues: string; showDesc: string }[]
  skus: Sku[]
}>({
  spuName: '',
  spuDescription: '',
  catalogId: 0,
  brandId: 0,
  weight: 0,
  publishStatus: 0,
  decript: [],
  images: [],
  bounds: {
    buyBounds: 0,
    growBounds: 0,
  },
  baseAttrs: [{ attrId: 0, attrValues: '', showDesc: '' }],
  skus: [],
})

const inputVisible = ref<{ view: boolean }[]>([{ view: false }])
const inputValue = ref<{ val: string }[]>([{ val: '' }])
const dataResp = ref({
  attrGroups: [
    {
      attrGroupId: 0,
      attrGroupName: '',
      attrs: [
        {
          attrId: 0,
          attrName: '',
          valueType: 0,
          valueSelect: '',
        },
      ],
    },
  ], // 后台返回的所有数据
  baseAttrs: [
    [
      {
        attrId: 0,
        attrValues: '',
        showDesc: 0,
      },
    ],
  ],
  saleAttrs: [
    {
      attrId: 0,
      attrName: '',
      searchType: 0,
      valueType: 0,
      icon: '',
      valueSelect: '',
      attrType: 0,
      enable: 0,
      catelogId: 0,
      showDesc: 0,
      attrGroupId: null,
      catelogName: '',
      groupName: null,
      catelogPath: null,
    },
  ],
  tempSaleAttrs: [
    {
      attrId: 0,
      attrValues: [],
      attrName: '',
    },
  ],
  tableAttrColumn: [
    {
      attrId: 0,
      attrValues: [],
      attrName: '',
    },
  ],
  memberLevels: [
    {
      id: 0,
      name: '',
      price: 0,
      priviledgeMemberPrice: 0,
    },
  ],
  steped: [false, false, false, false, false],
})
const catPtahStore = catBrandStore()
const { catPath, brandId } = storeToRefs(catPtahStore)

// 上一步
const prevStep = () => {
  if (step.value > 0) step.value--
}

// 下一步
const nextStep = () => {
  if (step.value < 4) step.value++
}

watch(brandId, (newBrandId: any) => {
  if (spu.value.catalogId === 0) {
    spu.value.brandId = 0
  }
  spu.value.brandId = newBrandId
})

watch(catPath, (newCatPath) => {
  if (newCatPath && newCatPath.length > 0) {
    spu.value.catalogId = newCatPath[newCatPath.length - 1]
  } else {
    spu.value.catalogId = 0
    spu.value.brandId = 0
  }
})

const collectSpuBaseInfo = async () => {
  nextStep()
  if (!dataResp.value.steped[0]) {
    try {
      const response = await reqBaseList(spu.value.catalogId)
      if (response && response.code === 0) {
        dataResp.value.baseAttrs = response.data.map((item: any) =>
          item.attrs.map((attr: any) => ({
            attrId: attr.attrId,
            attrValues: '',
            showDesc: attr.showDesc,
          })),
        )
        // dataResp.value.steped[0] = true
        dataResp.value.attrGroups = response.data
      }
    } catch (error) {
      console.error('SPU设置基本参数', error)
    }
  }
}

// step-2
const generateSaleAttrs = () => {
  nextStep()
  spu.value.baseAttrs = []
  dataResp.value.baseAttrs.map((item: any) => {
    item.map((attr: any) => {
      let { attrId, attrValues, showDesc } = attr
      if (attrValues && attrValues.length > 0) {
        if (attrValues instanceof Array) {
          attrValues = attrValues.join(';')
        }
        spu.value.baseAttrs.push({ attrId, attrValues, showDesc })
      }
    })
  })
  getShowSaleAttr()
}

const getShowSaleAttr = async () => {
  if (!dataResp.value.steped[1]) {
    try {
      const response = await reqAttrsList(spu.value.catalogId, 1, 100)
      if (response && response.code === 0) {
        console.log(response.page.list)
        dataResp.value.saleAttrs = response.page.list
        console.log(dataResp.value.saleAttrs)
        response.page.list.map((item: any) => {
          dataResp.value.tempSaleAttrs.push({
            attrId: item.attrId,
            attrValues: [],
            attrName: item.attrName,
          })
          inputVisible.value.push({ view: false })
          inputValue.value.push({ val: '' })
        })
        // dataResp.value.steped[1] = true
      }
    } catch (error) {
      console.log('销售属性:' + error)
    }
  }
}

const showInput = (idx: number) => {
  inputVisible.value[idx].view = true
}

const handleInputConfirm = (idx: number) => {
  let input = inputValue.value[idx].val
  if (input) {
    if (dataResp.value.saleAttrs[idx].valueSelect === '') {
      dataResp.value.saleAttrs[idx].valueSelect = input
    } else {
      dataResp.value.saleAttrs[idx].valueSelect += ';' + input
    }
  }
  inputVisible.value[idx].view = false
  inputValue.value[idx].val = ''
}

// step-3
const generateSkus = () => {
  nextStep()
  let selectValues: Array<{ attrValues: any[] }> = []
  dataResp.value.tableAttrColumn = []
  dataResp.value.tempSaleAttrs.map((item: any) => {
    if (item.attrValues.length > 0) {
      selectValues.push({ attrValues: item.attrValues })
      dataResp.value.tableAttrColumn.push({
        attrId: item.attrId,
        attrValues: item.attrValues,
        attrName: item.attrName,
      })
    }
  })
  let descartesArray = descartes(selectValues)
  console.log(JSON.stringify(descartesArray))
  let skus: Sku[] = []
  descartesArray.forEach((descartesItem) => {
    let attrArray: Array<{ attrId: any; attrName: string; attrValue: any }> = [] // sku属性组
    descartesItem.forEach((de, index) => {
      // 构造saleAttr信息
      let saleAttrItem = {
        attrId: dataResp.value.tableAttrColumn[index].attrId,
        attrName: dataResp.value.tableAttrColumn[index].attrName,
        attrValue: de,
      }
      attrArray.push(saleAttrItem)
    })

    let imgs: Array<{ imgUrl: string; defaultImg: number }> = []
    // spu.value.images.forEach(() => images.push({ imgUrl: '', defaultImg: 0 }))
    console.log(spu.value.images)
    spu.value.images.forEach(() => {
      imgs.push({ imgUrl: '', defaultImg: 0 })
    })
    // 会员价，也必须在循环里面生成，否则会导致数据绑定问题
    let memberPrices: Array<{ id: number; name: string; price: number }> = []
    if (dataResp.value.memberLevels.length > 0) {
      for (let i = 0; i < dataResp.value.memberLevels.length; i++) {
        if (dataResp.value.memberLevels[i].priviledgeMemberPrice === 1) {
          memberPrices.push({
            id: dataResp.value.memberLevels[i].id,
            name: dataResp.value.memberLevels[i].name,
            price: 0,
          })
        }
      }
    }

    let res = hasAndReturnSku(spu.value.skus, descartesItem)
    if (res === null) {
      skus.push({
        attr: attrArray,
        skuName: spu.value.spuName + ' ' + descartesItem.join(' '),
        price: 0,
        skuTitle: spu.value.spuName + ' ' + descartesItem.join(' '),
        skuSubtitle: '',
        images: imgs,
        descar: descartesItem,
        fullCount: 0,
        discount: 0,
        countStatus: 0,
        fullPrice: 0.0,
        reducePrice: 0.0,
        priceStatus: 0,
        memberPrice: [...memberPrices],
      })
    } else {
      skus.push(res)
    }
  })
  spu.value.skus = skus
  console.log('结果!!!', spu.value.skus, dataResp.value.tableAttrColumn)
}

const hasAndReturnSku = (skus: Array<Sku>, descar: string[]): Sku | null => {
  let res: Sku | null = null

  if (skus.length > 0) {
    for (let i = 0; i < skus.length; i++) {
      if (skus[i].descar.join(' ') === descar.join(' ')) {
        res = skus[i]
        break
      }
    }
  }
  return res
}

// 笛卡尔积运算
const descartes = (list: { attrValues: any[] }[]): any[][] => {
  if (!Array.isArray(list) || list.length === 0) return []

  let result: any[][] = []
  let point: number[] = new Array(list.length).fill(0)
  let temp: any[] = []
  let pIndex = 0
  while (true) {
    // 生成当前组合
    temp = list.map((obj) => obj.attrValues[point[list.indexOf(obj)]])
    result.push([...temp]) // 深拷贝保存当前组合
    // 更新指针，生成下一组数据
    for (pIndex = list.length - 1; pIndex >= 0; pIndex--) {
      if (point[pIndex] + 1 < list[pIndex].attrValues.length) {
        point[pIndex]++
        break
      }
      point[pIndex] = 0 // 当前位重置，进位
    }
    if (pIndex < 0) break // 结束条件：所有指针回归到 0
  }
  return result
}

// step-4
const checkDefaultImg = (row: any, index: number, img: string) => {
  row.images[index].imgUrl = img // 默认选中
  row.images[index].defaultImg = 1 // 修改标志位
  row.images.forEach((item: any, idx: number) => {
    if (idx !== index) {
      item.defaultImg = 0
    }
  })
}

const getRowKey = (item: any) => {
  return spu.value.skus.indexOf(item).toString()
}

// 保存
const submitSkus = () => {
  console.log('~~~~~', JSON.stringify(spu.value))
  ElMessageBox.confirm('将要提交商品数据，需要一小段时间，是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      const response = await reqSaveSpu(spu.value)
      if (response && response.code === 0) {
        ElMessage({
          type: 'success',
          message: '保存SPU信息成功',
        })
        nextStep()
      } else {
        ElMessage.error(response.msg)
      }
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消保存SPU信息',
      })
    })
}
const addAgain = () => {
  step.value = 0
  resetSpuData()
}

const resetSpuData = () => {
  spu.value = {
    spuName: '',
    spuDescription: '',
    catalogId: 0,
    brandId: 0,
    weight: 0,
    publishStatus: 0,
    decript: [],
    images: [],
    bounds: {
      buyBounds: 0,
      growBounds: 0,
    },
    baseAttrs: [],
    skus: [],
  }
}
</script>
<style scoped lang="scss">
.box-card {
  width: 100%;
  margin: 20px auto;
}

.col-box-show {
  -webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.el-steps--horizontal {
  padding: 20px;
}

.next-bottom {
  padding: 15px 0;
}

.image-card-flex-out {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  flex-basis: 2px;
}

.image-card-flex {
  width: 148px;
  height: 199px;
  margin: 20px 8px 10px 0;
}

.img-style {
  background: #f5f7fa;
  line-height: 44px;
}

.image-flex {
  display: flex;
  width: 148px;
  margin: 10px 0;
  justify-content: center;
}

.image-checkbox {
  flex-wrap: nowrap;
}

.el-tag,
.image-radio {
  vertical-align: middle;
}

.image-radio {
  margin-top: -2px;
  margin-right: 5px;
}
</style>
